package com.flux.ui.fragment

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.Toast

import com.flux.Consts
import com.flux.ui.activity.FBaseActivity
import com.flux.ui.interfaces.IDPBaseFragment
import com.flux.utils.LogUtil

import java.lang.ref.WeakReference

/**
 * Created on 2016/1/16.
 *
 * @author MartinKent
 */
abstract class FBaseFragment : Fragment(), IDPBaseFragment {

    private var rootViewContainer: RelativeLayout? = null

    private val mHandler = FragmentHandler(this)

    private var activity: FBaseActivity? = null

    override lateinit var attachedActivity: FBaseActivity

    override lateinit var rootView: View

    protected abstract val fragmentLayout: Int

    private var toast: Toast? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        this.activity = context as FBaseActivity
        attachedActivity = activity!!
    }


    override fun onDestroy() {
        mHandler.removeCallbacksAndMessages(null)
        super.onDestroy()
    }

    /**
     * onCreateView
     *
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        if (0 != fragmentLayout) {
            rootView = inflater.inflate(fragmentLayout, null)
            rootViewContainer = RelativeLayout(context)
            rootViewContainer!!.addView(rootView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
            return rootViewContainer
        }
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    /**
     * onViewCreated
     *
     * @param view
     * @param savedInstanceState
     */
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView(view)
        initData()
    }

    protected fun removeMessages(what: Int) {
        mHandler.removeMessages(what)
    }

    protected fun removeMessages(what: Int, obj: Any) {
        mHandler.removeMessages(what, obj)
    }

    protected fun removeCallbacks(r: Runnable) {
        mHandler.removeCallbacks(r)
    }

    protected fun removeCallbacks(r: Runnable, token: Any) {
        mHandler.removeCallbacks(r, token)
    }

    protected fun removeCallbacksAndMessages(token: Any) {
        mHandler.removeCallbacksAndMessages(token)
    }

    /**
     * sendEmptyMessage
     *
     * @param what
     */
    protected fun sendEmptyMessage(what: Int) {
        mHandler.sendEmptyMessage(what)
    }

    /**
     * sendEmptyMessage
     *
     * @param what
     * @param delay
     */
    protected fun sendEmptyMessageDelayed(what: Int, delay: Int) {
        mHandler.sendEmptyMessageDelayed(what, delay.toLong())
    }

    /**
     * sendMessage
     *
     * @param msg
     */
    protected fun sendMessage(msg: Message) {
        mHandler.sendMessage(msg)
    }

    /**
     * sendMessageDelayed
     *
     * @param msg
     * @param delay
     */
    protected fun sendMessageDelayed(msg: Message, delay: Int) {
        mHandler.sendMessageDelayed(msg, delay.toLong())
    }

    /**
     * post
     *
     * @param runnable
     */
    protected fun post(runnable: Runnable) {
        mHandler.post(runnable)
    }

    /**
     * postDelayed
     *
     * @param runnable
     * @param delay
     */
    protected fun postDelayed(runnable: Runnable, delay: Int) {
        mHandler.postDelayed(runnable, delay.toLong())
    }

    /**
     * postAtFrontOfQueue
     *
     * @param runnable
     */
    protected fun postAtFrontOfQueue(runnable: Runnable) {
        mHandler.postAtFrontOfQueue(runnable)
    }

    /**
     * initView
     *
     * @param view 视图
     */
    protected abstract fun initView(view: View?)

    /**
     * initData
     * run int background with AsyncTask.
     */
    protected abstract fun initData()

    /**
     * onHandleMessage.
     *
     * @param msg called when a message be handled
     */
    protected abstract fun onHandleMessage(msg: Message)

    /**
     * showToast
     *
     * @param resId
     */
    fun showToast(resId: Int) {
        showToast(getString(resId))
    }

    /**
     * showToast
     *
     * @param msg
     */
    fun showToast(msg: String) {
        if (null == toast) {
            toast = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT)
            toast!!.show()
        } else {
            toast!!.setText(msg)
            toast!!.show()
        }
    }

    /**
     * startActivity
     *
     * @param cls
     * @param extras
     */
    fun startActivity(cls: Class<*>, vararg extras: String) {
        val intent = Intent(attachedActivity, cls)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, extras)
        super.startActivity(intent)
    }

    /**
     * startActivity
     *
     * @param cls
     * @param extras
     */
    fun startActivityWithTaskCleared(cls: Class<*>, vararg extras: String) {
        val intent = Intent(attachedActivity, cls)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, extras)
        super.startActivity(intent)
    }

    /**
     * startActivityForResult
     *
     * @param cls
     * @param requestCode
     * @param data
     */
    fun startActivityForResult(cls: Class<*>, requestCode: Int, vararg data: String) {
        val intent = Intent(attachedActivity, cls)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, data)
        activity!!.startActivityForResult(intent, requestCode)
    }

    /**
     * onActivityResult
     *
     * @param requestCode 请求码
     * @param resultCode  结果码
     * @param data        返回数据
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        LogUtil.enter("requestCode=" + requestCode + ",resultCode=" + resultCode + ",data=" + (data?.toString() ?: "null"))
        if (null != data && data.hasExtra(Consts.ACTIVITY_RESULT_STRING_EXTRAS)) {
            onActivityResult(requestCode, resultCode, data.getStringArrayExtra(Consts.ACTIVITY_RESULT_STRING_EXTRAS))
        } else {
            onActivityResult(requestCode, resultCode, null as Array<String>?)
        }
    }

    /**
     * onActivityResult
     *
     * @param requestCode 请求码
     * @param resultCode  结果码
     * @param data        返回数据
     */
    open fun onActivityResult(requestCode: Int, resultCode: Int, data: Array<String>?) {

    }

    private class FragmentHandler(fragment: FBaseFragment) : Handler() {
        private val mFragment: WeakReference<FBaseFragment> = WeakReference(fragment)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val fragment = mFragment.get()
            fragment?.onHandleMessage(msg)
        }
    }

    /**
     * isEmpty
     *
     * @param src
     * @return isEmpty
     */
    protected fun isEmpty(src: String?): Boolean {
        return null == src || "" == src
    }

    /**
     * isEmpty
     *
     * @param src
     * @param <T>
     * @return isEmpty
    </T> */
    protected fun <T> isEmpty(src: Array<T>?): Boolean {
        return null == src || src.isEmpty()
    }

    /**
     * isEmpty
     *
     * @param src
     * @return isEmpty
     */
    protected fun isEmpty(src: List<*>?): Boolean {
        return null == src || src.isEmpty()
    }

    /**
     * isEmpty
     *
     * @param src
     * @return isEmpty
     */
    protected fun isEmpty(src: Map<*, *>?): Boolean {
        return null == src || src.isEmpty()
    }
}